#-*- coding: utf-8 -*-
#
# Copyright (C) 2006-2007 Ville Leskinen
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA

"""This module provides a Gallery object"""

import os
from string import Template

from imagelist import ImageList
from defaulttemplates import *
from errors import *
from listener import *

_thumbHTML="""<div class="thumb">
<p><a href="$LINK"><img src="$THUMB" alt="$EXPL" /></a></p>
</div>"""

_picHTML="""<img src="$PIC" alt="$EXPL" />"""

_navBackHTML="""<li><a href="$LINK">&lt;&lt;</a></li>"""
_navUpHTML="""<li><a href="$LINK">^</a></li>"""
_navForwardHTML="""<li><a href="$LINK">&gt;&gt;</a></li>"""

class Gallery(object):
	"""Gallery object for creating gallerys"""
	def __init__(self, imageList, thumbTemplate=None, picTemplate=None):
		"""
		Constructor

		@param imageList: ImageList object containing the image for gallery
		@type imageList: L{igCreator.imagelist.ImageList}
		@param thumbTemplate: html template for thumbnail page
		@type thumbTemplate: string.Template
		@param picTemplate: html template for picture pages
		@type picTemplate: string.Template
		"""
		self.imageList = imageList
		self.thumbTemplate = thumbTemplate
		self.picTemplate = picTemplate
		self.picDir='.'
		self.thumbDir = os.path.join(self.picDir, 'thumbs')
		self.heading = "Gallery"
		self.verbose = True
		self.cssfile = None
		self.cssBaseName = None
		

	def _readTemplate(self, filename):
		"""
		Returns a template read from a file.

		@param filename: file to read
		@type filename: string
		"""
		try:
			templateFile = file(filename, 'r')
			templateString = templateFile.read()
			template = Template(templateString)
			templateFile.close()
		except Exception, e:
			raise GalleryError, "Could not load template file %s: %s" % (filename, e)

		return template
		
	def readThumbTemplate(self, filename):
		"""
		Reads thumbnail template from a file.

		@param filename: file to read
		@type filename: string
		"""
		self.thumbTemplate = self._readTemplate(filename)

	def readPicTemplate(self, filename):
		"""
		Reads picture template from a file.

		@param filename: file to read
		@type filename: string
		"""
		self.picTemplate = self._readTemplate(filename)

	def setPath(self, path):
		"""
		Sets a path where the gallery will be created.

		@param path: path
		@type path: string
		"""
		self.picDir=path
		self.thumbDir= os.path.join(path, 'thumbs')

	def setHeading(self, heading):
		"""
		Sets a heading for the gallery.

		@param heading: the heading
		@type heading: string
		"""
		self.heading = heading

	def setCSSFile(self, cssfile):
		"""Sets a custom css file for the gallery.

		@param cssfile: path to the file
		@type cssfile: string"""
		self.cssfile = cssfile

	def create(self):
		"""Creates the gallery. This method also calls L{igCreator.imagelist.ImageList.create} for
		self.imageList, so there's no need to call it again."""

		self.imageList.create(self.picDir, self.thumbDir)

		if not len(self.imageList.thumbList) or not len(self.imageList.picList):
			raise GalleryError, "No image lists found" # We should never get here
		
		usingDefaultTemplates = False

		if not self.picTemplate:
			usingDefaultTemplates = True
			if self.verbose:
				print "No picture template given. Using default."
			self.picTemplate = Template(defaultPicHTML)

		if not self.thumbTemplate:
			usingDefaultTemplates = True
			if self.verbose:
				print "No thumbnail template given. Using default."
			self.thumbTemplate = Template(defaultThumbHTML)

		if usingDefaultTemplates and not self.cssfile:
			try:
				if self.verbose:
					print "Writing default stylesheet: default.css"
				cssFile = file(os.path.join(self.picDir, 'default.css'), 'w')
				cssFile.write(defaultCSS)
				cssFile.close()
				self.cssBaseName = "default.css"
			except Exception, e:
				raise GalleryError, "Problem writing default.css: %s" % (e)

		if self.cssfile:
			self._writeCssFile()

		self._generateHTML()


	def _writeCssFile(self):
		self.cssBaseName = os.path.basename(self.cssfile)

		origfile = file(self.cssfile, 'r')
		newfile = file(os.path.join(self.picDir, self.cssBaseName), 'w')
		newfile.writelines(origfile)

		origfile.close()
		newfile.close()


	def _generateHTML(self):
		thumbnailString = ""
		previousPicHTML = None

		for picName, thumbName in zip(self.imageList.picList, self.imageList.thumbList):
			(picBaseName, ext) = picName.split('.')
			picHTMLName = picBaseName + ".html"

			thumbHTMLTemplate = Template(_thumbHTML)
			thumbHTML = thumbHTMLTemplate.substitute(LINK = picHTMLName,
							THUMB = os.path.join('thumbs',thumbName),
							EXPL = picBaseName )

			thumbnailString = thumbnailString + thumbHTML + '\n'
			
			navigationString = ""

			if previousPicHTML:
				navBackTemplate = Template(_navBackHTML)
				navBack = navBackTemplate.substitute(LINK = previousPicHTML)
				navigationString = navBack + '\n'

			navUpTemplate = Template(_navUpHTML)
			navUp = navUpTemplate.safe_substitute(LINK = 'index.html')
			navigationString = navigationString + navUp + '\n'
			
			pos = self.imageList.picList.index(picName)
			if pos < len(self.imageList.picList) - 1:
				navForwardTemplate = Template(_navForwardHTML)
				(nextPicHTML, ext) =  self.imageList.picList[pos + 1].split('.')
				nextPicHTML = nextPicHTML + '.html'
				navForward = navForwardTemplate.substitute(LINK = nextPicHTML)

				navigationString = navigationString + navForward

			picHTMLTemplate = Template(_picHTML)
			picHTML = picHTMLTemplate.substitute(PIC = picName,
							EXPL = picBaseName)

			pictureHTML = self.picTemplate.safe_substitute(CSSFILE=self.cssBaseName,
								PICTITLE=picBaseName,
								PICTURE=picHTML,
								NAVIGATION = navigationString)

			if self.verbose:
				print "Creating file: %s" % (picHTMLName)
			picFile = file(os.path.join(self.picDir, picHTMLName), 'w')
			picFile.write(pictureHTML)
			picFile.close()

			previousPicHTML = picHTMLName
			

		thumbnailHTML = self.thumbTemplate.safe_substitute(CSSFILE=self.cssBaseName,
						TITLE = self.heading,
						THUMBS = thumbnailString )

		if self.verbose:
			print "Creating file: index.html"
		thumbFile = file(os.path.join(self.picDir, 'index.html'), 'w')
		thumbFile.write(thumbnailHTML)
		thumbFile.close()

class GalleryEvent(ListenerEvent):
	def __init__(self, message=None):
		ListenerEvent.__init__(self, 1, message)

class ListenableGallery(Gallery, Listenable):
	def __init__(self, imageList, thumbTemplate=None,  picTemplate=None):
		Gallery.__init__(self, imageList, thumbTemplate, picTemplate)
		Listenable.__init__(self)
		self.verbose = False

	def create(self):
		for l in self.listeners:
			l.addEvent(GalleryEvent())

		Gallery.create(self)

		for l in self.listeners:
			l.finished()

	def _generateHTML(self):
		self._eventHappening(GalleryEvent("Generating HTML"))
		Gallery._generateHTML(self)
